home *** CD-ROM | disk | FTP | other *** search
- /* Keyboard support routines.
- for Windows NT system.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
- #ifndef _OS_NT
- #error This file is for the NT operating system.
- #else
-
- #include <windows.h>
- #include <config.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <string.h>
- #include "tty.h"
- #include <ctype.h>
- #include <errno.h>
- #include <malloc.h>
- #include "util.h" /* For xmalloc prototype */
- #include "mad.h" /* The memory debugger */
- #include "global.h"
- #include "mouse.h"
- #include "key.h"
- #include "main.h"
- #include "file.h"
- #include "../vfs/vfs.h"
-
- /* "$Id: key.c,v 1.18 1995/02/21 19:06:13 miguel Exp $" */
- int old_esc_mode = 0;
- int double_click_speed; /* this two are not used... they are here to keep linker happy */
- int mou_auto_repeat;
- int use_8th_bit_as_meta = 0;
-
- /* Prototypes */
- static int EscapeKey (char* seq);
- static int ControlKey (char* seq);
- static int AltKey (char *seq);
-
- /* Static Tables */
- struct {
- int key_code;
- int vkcode;
- } key_table [] = {
- { KEY_F(1), VK_F1 },
- { KEY_F(2), VK_F2 },
- { KEY_F(3), VK_F3 },
- { KEY_F(4), VK_F4 },
- { KEY_F(5), VK_F5 },
- { KEY_F(6), VK_F6 },
- { KEY_F(7), VK_F7 },
- { KEY_F(8), VK_F8 },
- { KEY_F(9), VK_F9 },
- { KEY_F(10), VK_F10 },
- { KEY_F(11), VK_F11 },
- { KEY_F(12), VK_F12 },
- { KEY_F(13), VK_F13 },
- { KEY_F(14), VK_F14 },
- { KEY_F(15), VK_F15 },
- { KEY_F(16), VK_F16 },
- { KEY_F(17), VK_F17 },
- { KEY_F(18), VK_F18 },
- { KEY_F(19), VK_F19 },
- { KEY_F(20), VK_F20 },
- { KEY_IC, VK_INSERT },
- { KEY_DC, VK_DELETE },
- { KEY_BACKSPACE, VK_BACK },
- { '\t', VK_TAB },
- { KEY_ENTER, VK_RETURN },
- { KEY_ENTER, VK_EXECUTE },
- // { KEY_PRINT, VK_SNAPSHOT },
-
- { KEY_PPAGE, VK_PRIOR }, // Movement keys
- { KEY_NPAGE, VK_NEXT },
- { KEY_LEFT, VK_LEFT },
- { KEY_RIGHT, VK_RIGHT },
- { KEY_UP, VK_UP },
- { KEY_DOWN, VK_DOWN },
- { KEY_HOME, VK_HOME },
- { KEY_END, VK_END },
-
- { KEY_KP_MULTIPLY, VK_MULTIPLY }, // Numeric pad
- { KEY_KP_ADD, VK_ADD },
- { KEY_KP_SUBTRACT, VK_SUBTRACT },
- // { , VK_DIVIDE },
-
- /* Control key codes */
- { 0, VK_CONTROL }, /* Control */
- { 0, VK_MENU }, /* Alt */
- { 0, VK_ESCAPE }, /* ESC */
-
- /* Key codes to ignore */
- { -1, VK_SHIFT }, /* Shift when released generates a key event */
- { -1, VK_CAPITAL }, /* Caps-lock */
-
- #if WINVER >= 0x400 /* new Chicago key codes (not in 3.x headers) */
- { -1, VK_APPS }, /* "Application key" */
- { -1, VK_LWIN }, /* Left "Windows" key */
- { -1, VK_RWIN }, /* Right "Windows" key */
- #endif
-
- { 0, 0}
- };
-
- /* Special handlers for control key codes
- Note that howmany must be less than seq_buffer len
- ESC is not being handled right now. (S-lang returns ascii \e)
- */
- struct {
- int vkcode;
- int (*func_hdlr)(char *);
- int howmany;
- } key_control_table[] = {
- { VK_ESCAPE, EscapeKey, 1 },
- { VK_CONTROL, ControlKey, 1 },
- { VK_MENU, AltKey, 1 },
- { 0, NULL, 0},
- };
-
- void try_channels (int set_timeout)
- {
- }
- void channels_up()
- {
- }
- void channels_down()
- {
- }
-
- void init_key (void)
- {
- }
-
- /* The maximum sequence length (32 + null terminator) */
- static int seq_buffer[33];
- static int *seq_append = 0;
-
- static int push_char (int c)
- {
- if (!seq_append)
- seq_append = seq_buffer;
-
- if (seq_append == &(seq_buffer [sizeof (seq_buffer)-2]))
- return 0;
- *(seq_append++) = c;
- *seq_append = 0;
- return 1;
- }
-
- void define_sequence (int code, char* vkcode, int action)
- {
- }
-
- static int *pending_keys;
- int AltIsDown = 0;
-
- int correct_key_code (int c)
- {
- switch (c) {
- case KEY_KP_ADD: c = alternate_plus_minus ? ALT('+') : '+'; break;
- case KEY_KP_SUBTRACT: c = alternate_plus_minus ? ALT('-') : '-'; break;
- case KEY_KP_MULTIPLY: c = alternate_plus_minus ? ALT('*') : '*'; break;
- case -1:
- c = 0;
- break;
- default:
- break;
- }
-
- return c;
- }
-
- int get_key_code (int no_delay)
- {
- int c, i, k, j;
- static int lastnodelay = -1;
-
- if (no_delay != lastnodelay) {
- lastnodelay = no_delay;
- }
-
- pend_send:
- if (pending_keys) {
- int d = *pending_keys++;
- check_pend:
- if (!*pending_keys){
- pending_keys = 0;
- seq_append = 0;
- }
- /* if (d == ESC_CHAR && pending_keys){
- d = ALT(*pending_keys++);
- goto check_pend;
- }
- if ((d & 0x80) && use_8th_bit_as_meta)
- d = ALT(d & 0x7f);
- this = NULL;
- */ return correct_key_code (d);
- }
-
- if (no_delay) {
- nodelay (stdscr, TRUE);
- }
-
- c = xgetch ();
- if (no_delay) {
- nodelay (stdscr, FALSE);
- if (c == ERR)
- return ERR;
-
- } else if (c == ERR){
- /* Maybe we got an incomplete match.
- This we do only in delay mode, since otherwise
- xgetch can return ERR at any time. */
- return ERR;
- }
- /* S-Lang will return 0 and then a VK_CODE if char is not ascii
- That is because some VK codes are same as lower-case ascii (e.g. VK_F?) */
- if (c)
- return c;
- else
- c = xgetch();
-
- // Replace key code with that in table
- for (i=0; key_table[i].vkcode != 0 || key_table[i].key_code != 0; i++)
- if (c == key_table[i].vkcode) {
- if (key_table[i].key_code)
- return correct_key_code (key_table[i].key_code);
- else {
- // We special entries have 0 key_code, search them in control keys table
- for (j=0; key_control_table[j].vkcode != 0; j++) {
- if (key_control_table[j].vkcode == c) {
- /* Save as many keystrokes as asked */
- pending_keys = seq_append = NULL;
- for (k=0; k < key_control_table[j].howmany; k++)
- push_char(xgetch());
- /* Call special handler */
- c = key_control_table[j].func_hdlr (seq_buffer);
- if (!c) { /* handler asks us to return all the saved sequence */
- pending_keys = seq_buffer;
- goto pend_send;
- }
- }
- }
- }
- }
-
- return correct_key_code (c);
- }
-
- static int getch_with_delay (void)
- {
- int c;
-
- while (1) {
- /* Try to get a character */
- c = get_key_code (0);
- if (c != ERR)
- break;
- }
- /* Success -> return the character */
- return c;
- }
-
-
- extern int max_dirt_limit;
-
- /* Returns a character read from stdin with appropriate interpretation */
- /* Also takes care of generated mouse events */
- /* Returns 0 if it is a mouse event */
- /* The current behavior is to block allways */
- int get_event (Gpm_Event *event, int redo_event)
- {
- #define block 1
- int c;
- static int flag; /* Return value from select */
- static int dirty = 3;
-
- if ((dirty == 3) || is_idle ()){
- refresh ();
- doupdate ();
- dirty = 1;
- } else
- dirty++;
-
- vfs_timeout_handler ();
-
- /* Repeat if using mouse */
- #ifdef HAVE_SLANG
- while ((xmouse_flag) && !pending_keys)
- {
- SLms_GetEvent (event);
- }
- #endif
-
- #ifndef HAVE_SLANG
- #ifdef BUGGY_CURSES
- untouchwin (stdscr);
- #endif
- #endif
-
- c = getch_with_delay ();
- if (!c) { /* Code is 0, so this is a Control key or mouse event */
- #ifdef HAVE_SLANG
- SLms_GetEvent (event);
- #else
- ms_GetEvent (event); /* my curses */
- #endif
- return 0;
- }
-
- return c;
- }
-
- /* Returns a key press, mouse events are discarded */
- int mi_getch ()
- {
- Gpm_Event ev;
- int key;
-
- while ((key = get_event (&ev, 0)) == 0)
- ;
- return key;
- }
-
- /*
- Special handling of ESC key when old_esc_mode:
- ESC+ a-z,\n\t\v\r! = ALT(c)
- ESC + ' '|ESC = ESC
- ESC+0-9 = F(c-'0')
- */
- static int EscapeKey (char* seq)
- {
- int c = *seq;
-
- if (old_esc_mode) {
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
- || (c == '\n') || (c == '\t') || (c == XCTRL('h'))
- || (c == KEY_BACKSPACE) || (c == '!') || (c == '\r')
- || c == 127 || c == '+' || c == '-' || c == '\\'
- || c == '?')
- c = ALT(c);
- else if (isdigit(c))
- c = KEY_F (c-'0');
- else if (c == ' ')
- c = ESC_CHAR;
- return c;
- }
- else
- return 0; /* i.e. return esc then c */
- }
-
- /* Control and Alt
- */
- static int ControlKey (char* seq)
- {
- return XCTRL(*seq);
- }
- static int AltKey (char *seq)
- {
- return ALT(*seq);
- }
-
- /* A function to check if we're idle.
- It checks for any waiting event (that can be a Key, Mouse event,
- and other internal events like focus or menu) */
- int is_idle (void)
- {
- DWORD dw;
-
- static HANDLE hConsoleInput; /* This code should change, we need this handle */
- if (!hConsoleInput) /* as a global variable. Should think smthng. (and it should be the same as curses or s-lang handle) */
- hConsoleInput = GetStdHandle (STD_INPUT_HANDLE);
-
- if (GetNumberOfConsoleInputEvents (hConsoleInput, &dw))
- if (dw)
- return 0;
- return 1;
- }
-
- extern long SLsys_GetLastkeyControlState ();
-
- int ctrl_pressed ()
- {
- // if (HIWORD(GetKeyState (VK_CONTROL)))
- // return 1;
- // return 0;
- DWORD dwFlags = (DWORD) SLsys_GetLastkeyControlState();
- if (dwFlags & RIGHT_CTRL_PRESSED ||
- dwFlags & LEFT_CTRL_PRESSED)
- return 1;
-
- return 0;
- }
-
- #endif /* _OS_NT */
-